import data from "../../../../core/cache_data";
import { TouchHandle } from "../../../../core/data_ext";
import { ReplacePageAni } from "../../../../core/game";
import SoundManager from "../../../../core/sound_manager";
import Utils, { Random, Sync } from "../../../../core/utils";
import FrameBuffer from "../../../../prefabs/frame_buffer";
import CCCharacter from "../../../eggy/cc_game/cc_character";
import MutiTouch from "../../../some_good_prefab/assets/muti_touch";
import CCBomb from "../../cc_game/cc_bomb";
import { GameUtils } from "../../../eggy/game_utils";
import { Fight, FightResult } from "../../game/fight";
import CCCharacterBomb from "../../game/cc_character_bomb";

const { ccclass, property } = cc._decorator;

export enum PageGameStage {
    Ready = 1,
    Playing = 2,
    End = 3,
}

@ccclass
export default class PageGame extends cc.Component {
    @property(cc.Node)
    wrap: cc.Node = null;
    @property(cc.Node)
    root: cc.Node = null;
    @property(cc.Prefab)
    blowupPrefab: cc.Prefab = null;
    @property(cc.Animation)
    aniPlay: cc.Animation = null;
    @property(FrameBuffer)
    fb: FrameBuffer = null;

    ccChars: CCCharacterBomb[] = [];
    fight: Fight = null;
    _stage = PageGameStage.Ready;
    get stage() {
        return this._stage
    }
    set stage(val) {
        let old = this._stage
        this._stage = val;
        this.onStageChanged(old, val);
    }
    mutiTouch: MutiTouch = null;
    onStageChanged(old: PageGameStage, now: PageGameStage) {
    }
    protected onLoad(): void {
        this.fight = data.cache.get("fight");
        let degDt = 360 / this.fight.characters.length;
        let pt = cc.v2(440, 0);
        this.fight.characters.forEach(charData => {
            let char = GameUtils.InstantiateCCGameCom("eggy_bomb", CCCharacterBomb);
            char.on("get-next-char", this.onGetNextChar, this);
            this.ccChars.push(char);
            char.setData(charData);
            pt = pt.rotate(cc.misc.degreesToRadians(degDt));
            char.node.setPosition(pt.x, pt.y / 3.5);
            this.root.addChild(char.node);
            char.node.zIndex = 1000 - char.node.y;
        });

        this.mutiTouch = this.addComponent(MutiTouch);
        this.mutiTouch.on("end", this.onTouch, this);
    }
    onGetNextChar(msg: any) {
        let ind = this.ccChars.findIndex(ele => ele === msg.src);
        ind++;
        if (ind == this.ccChars.length) {
            ind = 0;
        }
        msg.dst = this.ccChars[ind];
    }
    onTouch(evt: TouchHandle) {
        // if (this.throwing) {
        //     return;
        // }
        let char = this.ccChars.find(char => {
            if (!char.isDead) {
                return char.touch.getBoundingBoxToWorld().contains(evt.loc)
            }
            return false;
        });
        if (char) {
            if (char.bomb) {
                let charInd = this.ccChars.findIndex(ele => ele === char);
                charInd++;
                if (charInd === this.ccChars.length) {
                    charInd = 0;
                }
                char.throw();
            }
        }
    }
    async start() {
        await Sync.AnimationEnd("", this.aniPlay);
        this.startGame();
    }

    protected onEnable(): void {
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
    }
    protected onDisable(): void {
        cc.systemEvent.targetOff(this);
    }
    onKeyDown(evt: cc.Event.EventKeyboard) {
        if (evt.keyCode === cc.macro.KEY.f2) {
            this.getComponentsInChildren(CCBomb).forEach(bomb => {
                this.onBlowup(bomb);
            });
            return;
        }
        if (evt.keyCode === cc.macro.KEY.f3) {
            this.stage = PageGameStage.End;
            Utils.game.resReplacePage({
                name: "page_ready",
                ani: ReplacePageAni.Fade
            });
        }
        if (evt.keyCode >= 48 && evt.keyCode <= 57) {
            let ind = evt.keyCode - 49;
            if (ind < 0) {
                ind = 9;
            }
            let char = this.ccChars[ind];
            char.throw();
        }
    }
    startGame() {
        this.stage = PageGameStage.Playing;
        for (let i = 0; i < this.fight.data.bombCount; i++) {
            this.genBomb();
        }
    }
    async endGame() {
        this.stage = PageGameStage.End;
        await Sync.DelayTime(1.0);
        let result = new FightResult();
        let char = this.ccChars[0];
        if (char) {
            result.characters = this.fight.characters.slice();
            result.winnerInd = result.characters.findIndex(ele => ele === char.character);
        }
        data.cache.set("result", result);
        Utils.game.resReplacePage({
            name: "page_result",
            ani: ReplacePageAni.Fade
        });
    }
    genBomb() {
        let bomb = GameUtils.InstantiateCCGameCom("cc_bomb", CCBomb);
        this.root.addChild(bomb.node);
        bomb.time = this.fight.data.time;
        bomb.on("blowup", this.onBlowup, this);
        bomb.node.zIndex = 9999;
        bomb.node.setPosition(0, 1000);
        //随机一个玩家
        let ind = Random.range(0, this.ccChars.length);
        let char = this.ccChars[ind];
        char.grab(bomb);
    }
    async onBlowup(bomb: CCBomb) {
        SoundManager.ins.playClip("blowup");
        let blowup = cc.instantiate(this.blowupPrefab);
        blowup.zIndex = 9999;
        this.root.addChild(blowup);
        blowup.setPosition(bomb.node.position);

        let owners = [bomb.ownerChar, bomb.dster];
        bomb.node.destroy();

        for (let i = 0; i < owners.length; i++) {
            let owner = owners[i];
            if (cc.isValid(owner)) {
                let sub = owner.node.position.sub(bomb.node.position);
                if (sub.len() < 320) {
                    owner.die();
                    let ind = this.ccChars.findIndex(char => char == owner);
                    this.ccChars.splice(ind,1);
                }
            }
        }

        this.wrap.setPosition(0, 0);
        cc.Tween.stopAllByTarget(this.wrap);
        cc.tween(this.wrap)
            .to(0.1, { x: -5, y: 4 })
            .to(0.1, { x: 5, y: -4 })
            .to(0.1, { x: -3, y: 2 })
            .to(0.1, { x: 2, y: -1 })
            .to(0.1, { x: 0, y: 0 })
            .start();

        await Sync.DelayTime(1.0);

        if (this.ccChars.length > 1) {
            this.genBomb();
        }
        else {
            this.endGame();
        }
    }
};